package com.myapp.utils;

import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Handler;

import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.myapp.MainApplication;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.SignatureException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import java.util.regex.Pattern;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;


/**
 * Created by Raul_lsj on 2018/3/5.
 */

public class AppUtils {

    public final static String PORTRAIT = "portrait";

    public final static String LANDSCAPE = "landscape";

    public static final String REGEX_NUM = "^(-)?\\d+(\\.\\d+)?$";

    public static final String PHONE_NUM = "^[1]\\d{10}$";

    public static final String NUM = "^[0-9]*$";


    public interface Callback {
        void onFinish();

    }

    private void isNull (String a) {
        if (a == null || a.length() ==0){

        }
    }


    public static void postRunnable(Runnable runnable, long mills){
        Handler handler = new Handler();
        handler.postDelayed(runnable,mills);
    }

    /**
     * px转dp
     *
     * @param context The context
     * @param px      the pixel value
     * @return value in dp
     */
    public static int pxToDp(Context context, float px) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        return (int) ((px / displayMetrics.density) + 0.5f);
    }

    /**
     * dp转px
     *
     * @param context
     * @param dp
     * @return
     */
    public static int dpToPx(Context context, float dp) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        return (int) ((dp * displayMetrics.density) + 0.5f);
    }


    /**
     * 获取状态栏高度
     *
     * @param context
     * @return
     */
    public static int getStatusBarHeight(Context context) {
        int result = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen",
                "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

    /**
     * 设置toolbar paddingTop
     * @param toolbarParent
     * @param mActivity
     */
    public static void setToolbarPadding(ViewGroup toolbarParent,Activity mActivity) {
   //     ViewGroup rootView = (ViewGroup) mActivity.getWindow().getDecorView().findViewById(android.R.id.content);
        toolbarParent.setPadding(0, getStatusBarHeight(mActivity), 0, 0);
    }


    public static boolean isEmptyOrNull(String target){
        return target == null || target.equals("");
    }

    /**
     * 改变状态栏文字颜色 6.0+
     * @param isBlack
     * @param activity
     */
    public static void changeStatusBarTextColor(boolean isBlack,Activity activity) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
            if (isBlack) {
                activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);//设置状态栏黑色字体
            }else {
                activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);//恢复状态栏白色字体
            }
        }
    }


    /**
     * 检查输入的格式 ，，数字 包含正负
     * @param input 字符串
     * @return false 不合格式 ，true 合格
     */
    public static boolean checkFigure(String input){
        Pattern pattern = Pattern.compile(AppUtils.REGEX_NUM);
        return pattern.matcher(input).matches();
    }

    /**
     * 检查输入是否是手机号
     * @param phoneNum
     * @return
     */
    public static boolean checkPhoneNum(String phoneNum){
        if (isEmptyOrNull(phoneNum))
            return false;
        return phoneNum.matches(PHONE_NUM);
    }

    /**
     * 检查纯数字
     * @param num
     * @return
     */
    public static boolean checkNum(String num){
        if (isEmptyOrNull(num)){
            return false;
        }
        return num.matches(NUM);
    }



    public static String integerTimeToString(int currentTime){

        String minute = String.valueOf(currentTime / 60);
        if (currentTime/60 < 10)
            minute = "0" + minute;
        String second = String.valueOf(currentTime % 60);
        if (currentTime % 60 < 10)
            second = "0" + second;

        return String.format(Locale.getDefault(),"%s:%s",minute,second);
    }


    /**
     * 给View 设置margin
     * @param v View
     * @param l dp
     * @param t dp
     * @param r dp
     * @param b dp
     */
    public static void margin(View v, int l, int t, int r, int b) {
        if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
            ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
            Context context = v.getContext();
            l = dpToPx(context,l);
            t = dpToPx(context,t);
            r = dpToPx(context,r);
            b = dpToPx(context,b);
            p.setMargins(l, t, r, b);
            v.setLayoutParams(p);
        }
    }


    /**
     * Return pseudo unique ID
     * @return ID
     */
    public static String getUniquePsuedoID()
    {
        // If all else fails, if the user does have lower than API 9 (lower
        // than Gingerbread), has reset their phone or 'Secure.ANDROID_ID'
        // returns 'null', then simply the ID returned will be solely based
        // off their Android device information. This is where the collisions
        // can happen.
        // Thanks http://www.pocketmagic.net/?p=1662!
        // Try not to use DISPLAY, HOST or ID - these items could change.
        // If there are collisions, there will be overlapping data
        String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);

        // Thanks to @Roman SL!
        // http://stackoverflow.com/a/4789483/950427
        // Only devices with API >= 9 have android.os.Build.SERIAL
        // http://developer.android.com/reference/android/os/Build.html#SERIAL
        // If a user upgrades software or roots their phone, there will be a duplicate entry
        String serial = null;
        try
        {
            serial = Build.class.getField("SERIAL").get(null).toString();

            // Go ahead and return the serial for api => 9
            return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
        }
        catch (Exception e)
        {
            // String needs to be initialized
            serial = "serial"; // some value
        }

        // Thanks @Joe!
        // http://stackoverflow.com/a/2853253/950427
        // Finally, combine the values we have found by using the UUID class to create a unique identifier
        return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
    }



    /**
     * 从控件所在位置移动到控件的底部
     *
     * @return
     */
    public static TranslateAnimation moveToViewBottom() {
        TranslateAnimation mHiddenAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
                0.0f, Animation.RELATIVE_TO_SELF, 1.0f);
        mHiddenAction.setDuration(300);
        return mHiddenAction;
    }

    /**
     * 从控件的底部移动到控件所在位置
     *
     * @return
     */
    public static TranslateAnimation moveToViewLocationBottom() {
        TranslateAnimation mHiddenAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
                1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
        mHiddenAction.setDuration(300);
        return mHiddenAction;
    }
    /**
     * 从控件的右边移动到控件所在位置
     *
     * @return
     */
    public static TranslateAnimation moveToViewLocationRight() {
        TranslateAnimation mHiddenAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1.0f,
                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
                0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
        mHiddenAction.setDuration(300);
        return mHiddenAction;
    }

    public static String dateToString(@NonNull String pattern, @NonNull Date date){
        SimpleDateFormat sd = new SimpleDateFormat(pattern,Locale.getDefault());
        return sd.format(date);
    }

    public static Date stringToDate(@NonNull String pattern, @NonNull String date) throws ParseException {
        SimpleDateFormat sd = new SimpleDateFormat(pattern,Locale.getDefault());
        return sd.parse(date);
    }

    /**
     * list的深拷贝
     * @param src
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(src);

        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
        ObjectInputStream in = new ObjectInputStream(byteIn);
        @SuppressWarnings("unchecked")
        List<T> dest = (List<T>) in.readObject();
        return dest;
    }

    /**
     * 隐藏软键盘(只适用于Activity，不适用于Fragment)
     */
    public static void hideSoftKeyboard(Activity activity) {
        View view = activity.getCurrentFocus();
        if (view != null) {
            InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    /**
     * 隐藏软键盘(可用于Activity，Fragment)
     */
    public static void hideSoftKeyboard(Context context, List<View> viewList) {
        if (viewList == null) return;

        InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);

        for (View v : viewList) {
            inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }
    /**
     * 隐藏软键盘(可用于Activity，Fragment)
     */
    public static void hideSoftKeyboard(Context context, ViewGroup group) {
        if (group == null) return;

        InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
        for (int i = 0 ; i < group.getChildCount(); i ++) {
            View v = group.getChildAt(i);
            inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }

    }


    /**
     * Generate HmacSHA1 signature with given data string and key
     * @param data
     * @param key
     * @return
     * @throws SignatureException
     */
    private String generateSignature(String data, String key) throws SignatureException {
        String result;
        try {
            // get an hmac_sha1 key from the raw key bytes
            SecretKeySpec signingKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA1");
            // get an hmac_sha1 Mac instance and initialize with the signing key
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(signingKey);
            // compute the hmac on input data bytes
            byte[] rawHmac = mac.doFinal(data.getBytes("UTF-8"));
            result = new String(android.util.Base64.encode(rawHmac, android.util.Base64.NO_WRAP),"utf-8");
        }
        catch (Exception e) {
            throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
        }
        return result;
    }


    public static String ipInt2Str(int ip) {
        return String.valueOf(ip >>> 24) + "." +
                String.valueOf((ip & 0xFFFFFF) >>> 16) + "." +
                String.valueOf((ip & 0xFFFF) >>> 8) + "." +
                String.valueOf(ip & 0xFF);
    }

    public static String ipInt2Str(int ip ,boolean mirror){
        if (mirror){
            return String.valueOf(ip & 0xff) + "." +
                    String.valueOf(ip >>8 & 0xff) + "."+
                    String.valueOf(ip >> 16 & 0xff) + "."+
                    String.valueOf(ip >> 24 & 0xff);
        }else {
            return ipInt2Str(ip);
        }

    }




}
